<?php
namespace api\modules\v1\models\circle;

use api\modules\v1\models\Common;
use api\modules\v1\models\friend\Friend;
use api\modules\v1\models\user\User;
use api\modules\v1\models\user\UserAttention;
use api\modules\v1\models\userLevel\UserLevel;
use common\models\CacheKeys;
use common\models\Functions;
use common\models\im\Im;
use common\models\Patterns;
use common\models\Status;
use common\models\user\UserUnusualLog;
use common\models\user\UserViewLog;
use phpDocumentor\Reflection\Types\Integer;
use Yii;
use yii\base\Exception;
use yii\helpers\ArrayHelper;
class Circle extends \common\models\circle\Circle
{


    public function rules()
    {
        return [
            #发送注册验证码
            [['content','images','is_see'], 'required','message' => '{attribute}不能为空','on' => 'addEdit'],
            [['title','content'],'filter','filter' => 'trim', 'on' => ['addEdit']],
            ['images', 'validateImage', 'on' => ['addEdit']],
        ];
    }

    public function attributeLabels() {
        return [
//            'title' => '标题',
            'content' => '内容',
            'images' => '图片',
            'is_see' => '是否可见',
            'is_comment' => '是否可评',
        ];
    }


    public function scenarios() {
        $newScenarios =  [
            'addEdit' => [
//                'title',
                'content',
                'images',
                'is_see',
                'is_comment',
            ],
        ];
        return array_merge(parent::scenarios(), $newScenarios);
    }

    // 验证图片数量
    public function validateImage($attribute) {
        if (!$this->hasErrors()) {
            $config = static::getCommonByKey(['circle_image_num']);
            if (count($this->images) > $config['circle_image_num']) {
                $this->addError($attribute, "图片最大为{$config['circle_image_num']}张");
            }
        }
    }

    /**
     * 获取配置
     */
    public function getConfig()
    {
        try{
            $data = [
                "禁止发布非法物品及违法广告类内容",
                "禁止发布威胁、煽动用户强制分享内容",
                "禁止发布涉及黄赌毒类相关内容",
                "禁止发布国家政治敏感词相关内容",
            ];
            return Functions::formatRestAPI(0, '', $data);
        }catch(Exception $e){
            return Functions::formatRestAPI(1,$e->getMessage());
        }
    }

    /**
     * 发布圈子
     * @return array
     */
    public function create() {
        $trans = static::getDb()->beginTransaction();
        try {
//            throw new Exception('升级中！');

            if (!$this->validate()) {
                throw new Exception($this->getErrorSummary(true)[0]);
            }

//            $user = Yii::$app->getUser()->getIdentity()->toArray();
            $user = (new User())->checkUser();

            if ($user['is_kyc'] != Status::COMMON_RADIO_YES) {
                throw new Exception('请先实名认证');
            }

            CacheKeys::checkFrequency($user['id'],1);
            //判断当前用户状态
            UserUnusualLog::checkUserUnusual($user['id'],Status::USER_UNUSUAL_TYPE_CIRCLE);

            $data = [];
            $data = array_merge($data, $this->getSaveData($this->scenario, Yii::$app->request->post()));

            // 过滤敏感词
            list($isSensitive,$afterStr) = Functions::sensitive($this->content);
//            var_dump($isSensitive);die;
//            if ($isSensitive) {
//                throw new Exception('发布内容不合法！');
//            }

            $wordNum = mb_strwidth($this->content);
            $currentLevelInfo = UserLevel::getOneByWhere(['id' => $user['level_id']]);
            if ($currentLevelInfo['greet_limit']) {
                if ($wordNum >= $currentLevelInfo['circle_word_limit']) {
                    throw new Exception('当前级别朋友圈文字上限为'.$currentLevelInfo['circle_word_limit'].'！');
                }
            }
            # 位置
            list($longitude,$latitude) = $this->getPosition($user['login_name']);
            if (empty($longitude) || empty($latitude)) {
                throw new Exception('未获取到位置信息！');
            }
            $data['longitude'] = $longitude;
            $data['latitude'] = $latitude;
            $data['user_id'] = $user['id'];
            $data['user_tx_code'] = $user['tx_code'];
            $data['images'] = json_encode($this->images,true);
            $data['status'] = Status::COMMON_CHECKING_SUCCESS;
            if ($isSensitive) {
                $data['status'] = Status::COMMON_CHECKING_WAITING;
            }

            $data['create_time'] = date('Y-m-d H:i:s');
            $res = static::insertData($data);
            if ($res === false) {
                throw new Exception('操作失败，请稍后尝试！');
            }

            $circleInfo = static::getObjectByAndWhere(['id' => $res], [], ['*'])->with([
                'user' => function ($q) {
                    $q -> select(['id','tx_code','nick_name','user_face']);
                },
            ])->asArray()->one();
            $singleUserInfo = ArrayHelper::getValue($circleInfo,'user',[]);

            $imageTmp = null;
            $imageArray = $circleInfo['images'] ? json_decode($circleInfo['images'],true) : [];
            if ($imageArray) {
                foreach ($imageArray as $vv) {
                    $imageTmp[] = static::getImages($vv);
                }
            }
            $msg = '发布成功!';

            $return = [
                'id' => (int) $circleInfo['id'],
//                'tx_code' => $singleUserInfo['tx_code'] ?: '',
                'user_face' => static::getAvatar($singleUserInfo['user_face']),
                'nick_name' => $singleUserInfo['nick_name'] ?? '',
                'content' => $circleInfo['content'],
                'images' => $imageTmp,
                'time' => strtotime($circleInfo['create_time']),
            ];
            if($data['status'] == Status::COMMON_CHECKING_WAITING){
                $msg = '等待审核!';
                $return = [];
            }

            $trans->commit();
            return Functions::formatRestAPI(0, $msg,$return);
        }
        catch (\yii\db\Exception $ee) {
            return Functions::formatRestAPI(1, '服务异常');
        }
        catch (Exception $e) {
            $trans->rollBack();
            return Functions::formatRestAPI($e->getCode() ? $e->getCode() : 1, $e->getMessage());
        }
    }

    /**
     * 圈子列表
     * @return array
     */
    public function getList()
    {
        try {
            $page = (int) Yii::$app->request->get('page',1);
            $size = (int) Yii::$app->request->get('size',20);
            $title = Yii::$app->request->get('title','');
            //类型   0：全部  1：我的  2： 关注  3：点赞   4：收藏 5：浏览
            $type = (int) Yii::$app->request->get('type',0);
            $code = (int) Yii::$app->request->get('code',0);  // 查看具体用户的圈子

//            $user = Yii::$app->getUser()->getIdentity()->toArray();
            $user = (new User())->checkUserNoExp();

            $userId = $user['id'] ?? 0;
            $levelInfo = UserLevel::getOneInfoById($user['level_id']);

            // 查看具体某个用户
            if($code){
                $viewUser = User::getOneByWhere(['tx_code'=>$code]);
                $userId = $viewUser['id'];
                if(empty($viewUser)){
                    throw new Exception('未知用户');
                }
                //加入浏览记录
                (new UserViewLog()) -> view($user,$viewUser);
            }

            $where = $andWhere = [];
            $where['is_delete'] = Status::COMMON_IS_NOT_DELETE;
            $where['status'] = Status::COMMON_CHECKING_SUCCESS;
//            $where['is_see'] = Status::COMMON_RADIO_YES;

            if($type == 1){
                //我的
                $where['user_id'] = $userId;
            }
            //如果是自己查看 全部显示
//            if($user['id'] && empty($code)){
//                unset($where['is_see']);
//            }
            if($type == 2){
                //关注
                $attentionIds = UserAttention::getFormArray(['user_id' => $userId],'topic_id','topic_id');
                $where['user_id'] = $attentionIds;
            }
            if($type == 3){
                //点赞
                $ids = CircleUserRelation::getFormArray(['user_id' => $userId,'type' => Status::CIRCLE_USER_RELATION_TYPE_LIKE],'circle_id','circle_id');
                $where['id'] = $ids;
            }
            if($type == 4){
                //收藏
                $ids = CircleUserRelation::getFormArray(['user_id' => $userId,'type' => Status::CIRCLE_USER_RELATION_TYPE_COLLECT],'circle_id','circle_id');
                $where['id'] = $ids;
            }
            if($type == 5){
                //浏览
                $ids = array_column(CircleUserRelation::getByWhere(['user_id' => $userId,'type' => Status::CIRCLE_USER_RELATION_TYPE_VIEW],'*','create_time DESC'),'circle_id');
                $where['id'] = $ids;
            }

            if ($title) {
                $andWhere[] = ['like','title',$title];
            }

            // 过滤掉不可以查看的用户  发现才会屏蔽
            $friendNotShowIds = Friend::getFormArray([
                'is_show_circle' => Status::COMMON_RADIO_NO,
                'user_id' => $user['id'],
            ],'friend_id','friend_id');
            //进别人详情都能看
            if($code){
                $friendNotShowIds = [];
            }

            //拉黑,我不看谁
            $blockList = UserAttention::getByAndWhere(['user_id' => $user['id'],'type' => Status::USER_ATTENTION_TYPE_BLOCK]);
            $blockIds = array_column($blockList,'topic_id');
            $notUserIds = array_unique(array_merge($friendNotShowIds,$blockIds));


            // 过滤掉已注销的用户
            $closeUserList = User::getByAndWhere(['is_delete' => 2 , 'status' => 2]);
            $closeIds = array_column($closeUserList,'id');
            $notUserIds = array_unique(array_merge($notUserIds,$closeIds));

            if ($notUserIds) {
                $andWhere[] = ['not in','user_id',$notUserIds];
            }



            //好友id
            $friendList = Friend::getByAndWhere(['user_id' => $user['id']]);
            $friendIds = array_column($friendList,'friend_id');
            $friendIds[] = $user['id'];

            // 不是非好友可见
            $andWhere[] = [
                'or',
                ['=','is_see',Status::COMMON_RADIO_YES],
                [
                    'and',
                    ['=','is_see',Status::COMMON_RADIO_NO],
                    ['IN','user_id',$friendIds],
                ]

            ];
//            $count = static::getCountByAndWhere($where,$andWhere);
//            $data = static::setPageinationAPI($page, $size, $count);

            list($longitude,$latitude) = $this->getPosition($user['phone']);
            $distanceField = "ROUND(
                6378.138 * 2 * ASIN(
                    SQRT(
                        POW(
                            SIN(
                                (
                                    {$latitude} * PI() / 180 - latitude * PI() / 180
                                ) / 2
                            ),
                            2
                        ) + COS({$latitude} * PI() / 180) * COS(latitude * PI() / 180) * POW(
                            SIN(
                                (
                                    {$longitude} * PI() / 180 - longitude * PI() / 180
                                ) / 2
                            ),
                            2
                        )
                    )
                ),5 
            ) AS distance";

            $data = static::setPaginationForApi($page);
            $offset = ($page - 1) * $size;
            $order = 'create_time DESC,id DESC';
            $list = static::getObjectByAndWhere($where, $andWhere, ['*',$distanceField], $order, $offset, $size)->with([
                'user' => function ($q) {
                    $q -> select(['id','user_face','nick_name','tx_code','sex','birthday','level_id','is_hiding']);
                },
                'like' => function ($q) use ($userId) {
                    $q -> select(['*']) -> where(['user_id' => $userId]);
                },
                'collect' => function ($q) use ($userId) {
                    $q -> select(['*']) -> where(['user_id' => $userId]);
                }
            ])->asArray()->all();

            // 查询在线状态
            $onLineResult = $list ? (new Im()) -> queryOnlineStatus(ArrayHelper::getColumn($list,'user_tx_code')) : [];

            $result = [];
            foreach ($list as $v) {
                $singleUserInfo = ArrayHelper::getValue($v,'user',[]);
                $singleLikeUserInfo = array_column(ArrayHelper::getValue($v,'like',[]),'user_id');
                $singleCollectUserInfo = array_column(ArrayHelper::getValue($v,'collect',[]),'user_id');

                $tmp = [
                    'id' => (int) $v['id'],
                    'user_id' => $singleUserInfo['id'] ?: '',
                    'tx_code' => $singleUserInfo['tx_code'] ?? '',
                    'user_face' => static::getAvatar($singleUserInfo['user_face']),
                    'nick_name' => $singleUserInfo['nick_name'] ?? '已注销',
                    'sex' => (int) $singleUserInfo['sex'],
                    'age' => $singleUserInfo['birthday'] ? Functions::birthday($singleUserInfo['birthday']) : 0,
                    'distance' => round($v['distance'],2),
                    'is_online' => false,
                    'title' => $v['title'],
                    'content' => $v['content'],
                    'images' => static::getAllImagesWithType($v['images']),
                    'is_like' => in_array($userId,$singleLikeUserInfo),
                    'like_num' => $v['like_num'] ?? 0,
//                    'time' => date('Y-m-d',strtotime($v['create_time'])),
                    'time' => date('Y-m-d H:i:s',strtotime($v['create_time'])),
                    'collect_num' => $v['collect_num'] ?? 0,
                    'comment_num' => $v['comment_num'] ?? 0,
                    'is_collect' => in_array($userId,$singleCollectUserInfo),
                    'is_see' => $v['is_see'],
                    'is_comment' => (int) $v['is_comment'], // 是否可评 1-是 2-否
                ];

                $tmp['distance'] = User::handleDistance($levelInfo,$singleUserInfo,$tmp['distance']);

//                if($levelInfo['show_nearby'] == Status::COMMON_RADIO_NO ){
//                    $tmp['distance'] = ">100KM";
//                } else {
////                    $tmp['distance'] = $tmp['distance'] ? $tmp['distance'].'KM' : '未知';
//                    $tmp['distance'] = $tmp['distance'].'KM';
//                }

                if ($onLineResult) {
                    foreach ($onLineResult as $kk => $vv) {
                        if ($vv['To_Account'] == $v['user_tx_code']) {
                            $tmp['is_online'] = $vv['Status'] == 'Online' ? true : false;
                            continue;
                        }
                    }
                }

                $result[] = $tmp;
            }

            $data['data'] = $result;
            return Functions::formatRestAPI(0, '', $data);
        }  catch (\yii\db\Exception $ee) {
            return Functions::formatRestAPI(1, '服务异常');
        } catch(Exception $e){
            return Functions::formatRestAPI($e->getCode() ? $e->getCode() : 1, $e->getMessage());
        }
    }

    /**
     * 圈子详情
     * @param Integer $id
     * @return array
     */
    public function info($id = 0)
    {
        try{
            if (empty($id)) {
                throw new Exception('参数错误');
            }

//            $user = Yii::$app->getUser()->getIdentity()->toArray();
            $user = (new User())->checkUserNoExp();

            $where = $andWhere = [];
            $where['is_delete'] = Status::COMMON_IS_NOT_DELETE;
            $where['status'] = Status::COMMON_CHECKING_SUCCESS;
            $where['id'] = $id;
            $info = static::getObjectByAndWhere($where, $andWhere, ['*'])->with([
                'user' => function ($q) {
                    $q -> select(['id','user_face','nick_name','tx_code']);
                },
                'like' => function ($q) use ($user) {
                    $q -> select(['*']) -> where(['user_id' => $user['id']]);
                },
                'collect' => function ($q) use ($user) {
                    $q -> select(['*']) -> where(['user_id' => $user['id']]);
                }
            ])->asArray()->one();

            if (empty($info)) {
                throw new Exception('未知信息');
            }

//            if($info['user_id'] != $user['id']) {
//                //是否是好友
//                $isFriendWhere = $isFriendAndWhere = [];
//                $isFriendWhere['user_id'] = $user['id'];
//                $isFriendWhere['friend_id'] = $info['user_id'];
//                $isFriend = Friend::getOneByWhere($isFriendWhere,'id');
//                if (empty($isFriend)) {
//                    throw new Exception('您和他不是好友，不能查看！');
//                }
//            }

            $singleUserInfo = ArrayHelper::getValue($info,'user',[]);
            $singleLikeUserInfo = array_column(ArrayHelper::getValue($info,'like',[]),'user_id');
            $singleCollectUserInfo = array_column(ArrayHelper::getValue($info,'collect',[]),'user_id');

            $imageTmp = static::getAllImagesWithType($info['images']);


            //关注
            $isAttention = 2;
            if ($user) {
                $followList = UserAttention::getByAndWhere(['user_id' => $user['id'],'type'=>Status::USER_ATTENTION_TYPE_FOLLOW]);
                $followIds = array_column($followList,'topic_id');

                if(in_array($singleUserInfo['id'],$followIds)){
                    $isAttention = 1;
                }else{
                    $isAttention = 2;
                }
                if($singleUserInfo['id'] == $user['id'] ){
                    $isAttention = 3;
                }
            }


            //星标
            $isStar = 2;
            if ($user) {
                $starList = UserAttention::getByAndWhere(['user_id' => $user['id'], 'type' => Status::USER_ATTENTION_TYPE_STAR]);
                $starIds = array_column($starList, 'topic_id');
                if (in_array($singleUserInfo['id'], $starIds)) {
                    $isStar = 1;
                } else {
                    $isStar = 2;
                }
            }
            $data = [
                'id' => (int) $info['id'],
                'user_id' => $singleUserInfo['id'],
                'tx_code' => $singleUserInfo['tx_code'],
                'user_face' => static::getAvatar($singleUserInfo['user_face']),
                'nick_name' => $singleUserInfo['nick_name'] ?? '',
                'content' => $info['content'],
                'images' => $imageTmp,
                'is_like' => in_array($user['id'] ?? 0,$singleLikeUserInfo),
                'is_collect' => in_array($user['id'] ?? 0,$singleCollectUserInfo),
                'time' => date('Y-m-d',strtotime($info['create_time'])),
                'like_num' => (int) $info['like_num'],
                'collect_num' => (int) $info['collect_num'],
                'comment_num' => (int) $info['comment_num'],
                'is_attention' => $isAttention,
                'is_star' => $isStar,
                'is_comment' => (int) $info['is_comment'], // 是否可评 1-是 2-否
            ];

            //加入浏览记录
            if ($user) {
                (new CircleUserRelation()) -> view($info,$user);
            }

            return Functions::formatRestAPI(0, '', $data);
        }catch(Exception $e){
            return Functions::formatRestAPI(1,$e->getMessage());
        }
    }

    /**
     *  删除圈子
     * @param Integer $id
     * @return array
     */
    public function deleteCircle($id = 0)
    {
        try {
            $user = Yii::$app->getUser()->getIdentity()->toArray();

            $id = $id ? $id : (int)Yii::$app->request->post('id',0);

            if (empty($id)) {
                throw new Exception('参数错误');
            }
            $where['id'] = $id;
            $where['user_id'] = $user['id'];
            $where['is_delete'] = Status::COMMON_IS_NOT_DELETE;
            $info = static::getOneByWhere($where);
            if (empty($info)) {
                throw new Exception('信息错误');
            }

            //修改圈子表数据
            $update = static::updateData(['is_delete' => Status::COMMON_RADIO_YES],['id' => $id]);
            if ($update === false) {
                throw new Exception('删除失败');
            }

            return Functions::formatRestAPI(0, '删除成功');
        }catch(Exception $e){
            return Functions::formatRestAPI(1,$e->getMessage());
        }
    }


}
